<?php

/**
 * Project: Espolon
 * Licence: BSD License
 * Link: http://espolon.org/
 * Copyright: Nicolas de Bari Embriz Garcia Rojas <nbari at espolon dot org>
 * Author: Nicolas de Bari Embriz Garcia Rojas <nbari at espolon dot org>
 * Version: Beta
 */

class User extends Dispatcher {
  /**
   * elementos del usuario
   */
  private $uid;
  private $login;
  private $firstname;
  private $lastname;
  private $email;
  private $hide_email;
  private $password;
  private $sex;
  private $hide_sex;
  private $confirmCode;
  private $active;
  private $created;
  private $changed;
  private $theme;
  private $language;
  private $login_info;
  private $force_login;
  private $remember;
  /**
   * elementos de configuracion
   */
	private $from;
	private $subject;
	private $body;
	private $emailSubject;
	private $emailBody;
	private $msg;

  function setUid($uid) { $this->uid = $uid; }
  function setLogin($login) { $this->login = $login; }
  function setFirstname($firstname) { $this->firstname = $firstname; }
  function setLastname($lastname) { $this->lastname = $lastname; }
  function setEmail($email) { $this->email = $email; }
  function setPassword($password) { $this->password = $password; }
  function setSex($sex) { $this->sex = $sex; }
  function setFrom($from) { $this->from = $from; }
  function setSubject($subject) { $this->subject = $subject; }
  function setBody($body) { $this->body = $body; }
  function setConfirmCode($confirmCode) { $this->confirmCode = $confirmCode; }
  function setEmailSubject($emailSubject) { $this->emailSubject = trim($emailSubject); }
  function setEmailBody($emailBody) { $this->emailBody = trim($emailBody); }
  function setLogin_info($login_info) { $this->login_info = $login_info; }
  function setForce_login($force_login) { $this->force_login = $force_login; }
  function setRemember($remember) { $this->remember = $remember; }
  function setMsg($msg) {$this->msg = $msg; }

  function getUid() { return $this->uid; }
  function getLogin() { return $this->login; }
  function getFirstname() { return $this->firstname; }
  function getLastname() { return $this->lastname; }
  function getEmail() { return $this->email; }
  function getPassword() { return $this->password; }
  function getSex() { return $this->sex; }
  function getFrom() { return $this->from; }
  function getSubject() { return $this->subject; }
  function getBody() { return $this->body; }
  function getConfirmCode() { return $this->confirmCode; }
  function getEmailSubject() { return $this->emailSubject; }
  function getEmailBody() { return $this->emailBody; }
  function getLogin_info() { return $this->login_info; }
  function getForce_login() { return $this->force_login; }
  function getRemember() { return $this->remember; }
	function getMsg() { return $this->msg; }

  function createCode ($login) {
    srand((double)microtime() * 1000000);
    $this->confirmCode = sha1($login . time() . rand(1, 1000000));
  }

  function generatePassword ($length = 8) {
    $password = "";
    $possible = "0123456789bcdfghjkmnpqrstvwxyz";
    $i = 0;
    while ($i < $length) {
      // pick a random character from the possible ones
      $char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
      // we don't want this character if it's already in the password
      if (!strstr($password, $char)) {
        $password .= $char;
        $i++;
      }
    }
    $this->setPassword($password);
  }

  function pw_encode($password) {
    $login = sess_get('login') ? sess_get('login') : $this->getLogin();
    return sha1($login.$password);
  }

  function pw_check($password, $stored_password) {
    if (strlen($stored_password) != 40) {
      return false;
    } else {
      #return (bin2hex(mhash(MHASH_SHA1, $_COOKIE['sess'], $stored_password)) == $password) ? true : false;
      return (hash_hmac('sha1', $_COOKIE['sess'], $stored_password) == $password) ? true : false;
    }
  }

  function createSignup ($userDetails) {
	  $record['firstname'] = $userDetails['firstname'];
	  $record['lastname']  = $userDetails['lastname'];
	  $record['email']     = $userDetails['email'];
	  $this->email         = $userDetails['email'];
	  $record['login']     = $userDetails['login'];
	  $this->setLogin($userDetails['login']);
	  $record['password']  = $this->pw_encode($userDetails['password1']);
	  $record['sex']       = $userDetails['sex'];
    $this->createCode($userDetails['login']);
    $record['confirm_code'] = $this->confirmCode;
    $record['created'] = date("Y-m-d H:i:s");
    $record['login_ip'] = $_SERVER['REMOTE_ADDR'];
    $record['login_host'] = gethostbyaddr($_SERVER['REMOTE_ADDR']);
    $result = $this->getDb()->AutoExecute('core_users', $record, 'INSERT');
    if (!$result) {
      $this->setMsg($this->getDb()->ErrorMsg());
    } else {
      $this->sendConfirmation();
    }
  }

  function sendConfirmation () {
	  $mail = new MyMailer;
    $mail->From = $this->getConfig('email_from');
    $mail->FromName = $this->getConfig('email_fromname');
    $mail->AddAddress($this->getEmail());
    $mail->Subject = html_entity_decode($this->getEmailSubject()); // áéíóúñ
    $url = "<a href=\"$_SERVER[HTTP_REFERER]/code/$this->confirmCode\">$_SERVER[HTTP_REFERER]/code/$this->confirmCode</a>";
    $msg = str_replace('__login__', $this->getLogin(), $this->getEmailBody());
    $msg = str_replace('__sitename__', $this->getConfig('site_name'), $msg);
    $msg = str_replace('__url__', $url, $msg);
    $mail->Body = $msg;
    $mail->AltBody = html_entity_decode(strip_tags(str_replace('<br>',' ',$msg)));
    if(!$mail->Send()) { $this->setMsg(_('error sending confirmation code')); };
  }

  function confirmCode ($code,$case='new_user') {
	if (strlen($code) != 40) {
	  return false;
	} else {
	  $active = ($case == 'new_user') ? '0' : '2';
	  $rs = $this->getDb()->GetRow("SELECT * FROM core_users WHERE confirm_code=".quote_smart($code)." AND active='$active'");
	  if(!$rs) {
		return false;
	  } else {
		if ($case == 'new_user') {
		  $rs = $this->getDb()->Execute("UPDATE core_users SET active='1' WHERE confirm_code=".quote_smart($code)."");
		} else {
		  $this->generatePassword();
		  $this->setLogin($rs['login']);
		  $rs = $this->getDb()->Execute("UPDATE core_users SET active='1', password='".$this->pw_encode(sha1($this->getPassword()))."' WHERE confirm_code='$code'");
		}
		if(!$rs) { $this->setMsg($this->getDb()->ErrorMsg()); return false; } else { return true; }
	  }
	}
  }

  function checkExists($post) {
	  if ($post == 'password') {
	    $operator = ($this->getLogin() == '' || $this->getEmail() == '') ? 'OR' : 'AND';
	    $rs = $this->getDb()->GetRow("SELECT * FROM core_users WHERE login=".quote_smart($this->getLogin())." $operator email='".$this->getEmail()."'");
	    if(!$rs) { $this->setMsg($this->getDb()->ErrorMsg()); return false; } else { return true; }
	  } else {
	    $value = ($post == 'login') ? $this->getLogin() : $this->getEmail();
	    $rs = $this->getDb()->GetRow("SELECT * FROM core_users WHERE $post=".quote_smart($value)."");
	    if(!$rs) { $this->setMsg($this->getDb()->ErrorMsg()); return true; } else { return false; }
    }
  }

  function authenticateUser () {
    if(!sess_get('uid')) {
      $auth = ($this->pw_check($this->getPassword(), $this->getDb()->GetOne("SELECT password FROM core_users WHERE login=".quote_smart($this->getLogin())." AND active != 0"))) ? $this->getDb()->GetRow("SELECT * FROM core_users WHERE login=".quote_smart($this->getLogin())."") : false ;
      if(!$auth) {
        $this->setMsg($this->getDb()->ErrorMsg());
        return false;  // bad username or password
      } elseif ($this->getConfig('avoid_logging_twice')) {  // avoid logging twice
        if ($this->getForce_login()) {
          return $this->login($auth);
        } else {
          $sess = isset($_COOKIE['sess']) ? $_COOKIE['sess'] : null;
          $online = $this->getDb()->GetCol("SELECT expireref FROM core_sessions2 WHERE SESSKEY !=".quote_smart($sess)." AND expiry > NOW()"); // get online users
          if (in_array($auth['uid'], $online)) {
            $this->setForce_login(($this->getConfig('allow_force_login') ? true : false));   // allow force login
            $this->setMsg($this->getTpl()->get_config_vars('logged_in_twice'));
            return false;
          } else {
            return $this->login($auth);
          }
        }
      } else { return $this->login($auth); }  // logging twice enabled
    } // end of if sess_get(uid)
  } // end of function

  function login($auth) {
    $cookie_token = md5(uniqid(rand(), true));
    $rs = $this->getDb()->Execute("UPDATE core_users SET login_ip=".quote_smart($_SERVER['REMOTE_ADDR']).", login_host=".quote_smart(gethostbyaddr($_SERVER['REMOTE_ADDR'])).", login_date=(NOW()), login_count=login_count+1, cookie='$cookie_token' WHERE login=".quote_smart($this->getLogin())."");
    if(!$rs) {
      $this->setMsg($this->getDb()->ErrorMsg());
      return false;
    } else {
      if ($this->getConfig('avoid_logging_twice')) {
        $rs = $this->getDb()->Execute("DELETE FROM core_sessions2 WHERE expireref=".quote_smart($auth['uid'])."");
        $this->setMsg($this->getDb()->ErrorMsg());
      }
      $GLOBALS['UID'] =  $auth['uid'];
      setcookie('sess', session_id(), time()+86400, '/');     # 24 horas
      if ($this->getRemember()) {
        $cookie = base64_encode(serialize(array($auth['uid'], sha1($_SERVER['HTTP_ACCEPT_LANGUAGE'].$_SERVER['HTTP_USER_AGENT']), $cookie_token)));
        setcookie('rmb', $cookie, time() + 2592000, '/');
      }
      sess_set('uid', $auth['uid']);
      sess_set('login', $auth['login']);
      sess_set('login_ip', $auth['login_ip']);
      sess_set('login_host', $auth['login_host']);
      sess_set('login_date', $auth['login_date']);
      sess_set('login_count', $auth['login_count']);
      $this->checkPerms();
      return true;
    }
  } // end of function

  function check_ahosts() {
    $rs = $this->getDB()->GetOne("SELECT ahosts FROM core_users WHERE login=".quote_smart($this->getLogin())."");

    if (!$rs) {
      return true;
    } else {
      $IP = $_SERVER['REMOTE_ADDR'];
      $ahosts = explode('|',$rs);
      foreach ($ahosts as $host) {
        if (in_array($IP, gethostbynamel($host))) {
          return true;
          break;
        }
      } // end foreach
      // save login attempts
      $ua = $_SERVER["HTTP_USER_AGENT"];
      $this->getDB()->Execute("INSERT INTO login_attempts SET user=".quote_smart($this->getLogin()).", ip ='$IP', hostname=".quote_smart(gethostbyaddr($_SERVER['REMOTE_ADDR'])).", ua='$ua', date=(now())");
      return false;
    }
  }

  function lostPassword() {
    $rs = $this->getDB()->GetRow("SELECT uid, login, email FROM core_users WHERE login=".quote_smart($this->getLogin())." OR email=".quote_smart($this->getEmail())."");
    if(!$rs) {
      $this->setMsg($this->getDB()->ErrorMsg());
    } else {
      $this->createCode($rs['login']);
      $this->setEmail($rs['email']);
      $this->setLogin($rs['login']);
      $rs = $this->getDB()->Execute("UPDATE core_users SET active='2', confirm_code='".$this->confirmCode."' WHERE uid='".$rs['uid']."'");
      if(!$rs) {
        $this->setMsg($this->getDB()->ErrorMsg());
      } else {
        $this->sendConfirmation();
      }
    }
  }

  function change_password() {
    $rs = $this->getDb()->Execute("UPDATE core_users SET password='".$this->pw_encode($this->getPassword())."' WHERE uid=".sess_get('uid')."");
    if(!$rs) { $this->setMsg($this->getDb()->ErrorMsg()); return false; } else { return true; }
  }

} // end of class

?>